<html>

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="TingGe Blog Agile agile JavaScript NodeJS">
  <meta name="author" content="TingGe<505253293@163.com>">
  <title>听歌实验室</title>
  <link type="image/x-icon" rel="shortcut icon" href="https://avatars3.githubusercontent.com/u/4074517?v=3&s=40" />
  <link rel="stylesheet" type="text/css" href="/lib/bootstrap/dist/css/bootstrap.min.css" media="screen">
  <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic,700italic" rel="stylesheet" type="text/css">
  <link href="/css/landing-page.css" rel="stylesheet">
  <link href="/css/screenshots.css" rel="stylesheet">
  <style media="screen">
    #main {
      padding-top: 55px;
    }
  </style>
  <script type="text/javascript" src="/lib/jquery/dist/jquery.min.js"></script>
  <script type="text/javascript" src="/lib/html2canvas/dist/html2canvas.min.js"></script>
  <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
        <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>

<body>
  <!-- Navigation -->
  <nav class="navbar navbar-default navbar-fixed-top topnav" role="navigation">
    <div class="container topnav">
      <!-- Brand and toggle get grouped for better mobile display -->
      <div class="navbar-header">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand topnav" href="/">
          <i class="fa fa-flask icon-3x" aria-hidden="true"></i> 听歌实验室
        </a>
      </div>
      <!-- Collect the nav links, forms, and other content for toggling -->
      <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
        <ul class="nav navbar-nav navbar-right">
          <li>
            <a href="/html/js.html">JavaScript/NodeJS</a>
          </li>
          <li>
            <a href="/index.html#agile">敏捷/项目管理(Agile/PMP)</a>
          </li>
          <li>
            <a href="/html/cloud-bi.html">云商业智能(Cloud BI)</a>
          </li>
          <li>
            <a href="/html/iot.html">物联网(WoT/IoT)</a>
          </li>
          <li>
            <a href="/html/me.html">关于我</a>
          </li>
        </ul>
      </div>
      <!-- /.navbar-collapse -->
    </div>
    <!-- /.container -->
  </nav>
  <div id="main" class="container">
    <div class="row">
      <div id="article" class="col-md-9 content-container">
        <h1 id="-docker-registry-">部署私有 Docker Registry 服务</h1>
<p>[TOC]</p>
<p>三种部署方式：</p>
<ul>
<li>Docker Registry 里有一个 <a href="https://hub.docker.com/_/registry/">registry 镜像</a>可协助部署私有Docker Registry 服务。该 Registry 镜像对本地测试足矣，但不能用于生产环境。</li>
</ul>
<ul>
<li>对于生产环境，应以 <a href="https://github.com/docker/docker/tree/master/distribution">docker/distribution</a> 为基础，自行配置并构建自定义 Registry 镜像。</li>
<li>配置 “Registry ＋ Nginx” 的方式，适合 v1 及 v2 版本并存。不再冗述。 </li>
</ul>
<p>以 Ubuntu Trusty 14.04 (LTS)  部署为例，建议 <strong>sudo</strong> 或 <strong>root</strong> 下执行。</p>
<h2 id="docker-registry-">Docker 官方 Registry 镜像</h2>
<ol>
<li><p><a href="https://docs.docker.com/engine/installation/linux/ubuntulinux/">安装 Docker</a>。</p>
</li>
<li><p>从 Docker 公共 Registry 中运行 hello-world  镜像：</p>
<pre><code class="lang-shell">docker run hello-world
</code></pre>
</li>
<li><p>在 localhost 上启动 Registry 服务：</p>
<pre><code class="lang-shell">docker run -p 5000:5000 registry:2
</code></pre>
</li>
<li><p>列出镜像：</p>
<pre><code class="lang-shell">docker images
</code></pre>
</li>
<li><p>把本地 repoistory 重新标记 <code>hello-world</code> 镜像：</p>
<pre><code class="lang-shell">docker tag hello-world:latest localhost:5000/hello-mine:latest
</code></pre>
<p>此命令使用 <code>[REGISTRYHOST/]NAME[:TAG]</code> 格式为 <code>hello-world:latest</code> 重新打标签。<code>REGISTRYHOST</code> 在此例中是 <code>localhost</code>。在 Mac OSX 环境中， <code>localhost</code> 换成 <code>$(boot2docker ip):5000</code></p>
</li>
<li><p>推送新镜像到本地 Registry 中：</p>
<pre><code class="lang-shell">docker push localhost:5000/hello-mine:latest
</code></pre>
</li>
<li><p>使用 <code>curl</code> 命令及 Docker Registry 服务 API v2 列出 Registry 中的镜像：</p>
<pre><code class="lang-shell">curl -v -X GET http://localhost:5000/v2/hello-mine/tags/list
</code></pre>
</li>
<li><p>从你的本地环境中移除所有未使用的镜像：</p>
<pre><code class="lang-shell">docker rmi -f $(docker images -q -a )
</code></pre>
<p>此命令仅用于说明目的；移除镜像强制 <code>run</code> 从 Registry 而不是从本地缓存拉取。如果在这之后运行<code>docker images</code>，在你的镜像列表中，应该看不到任何 <code>hello-world</code> 或 <code>hello-mine</code> 的实例</p>
</li>
<li><p>尝试从指定镜像的 Registry 来运行镜像：</p>
<pre><code class="lang-shell">docker run localhost:5000/hello-mine
</code></pre>
</li>
<li><p>之后运行 <code>docker images</code>， 你会发现里面多了一个 <code>hello-mine</code> 实例。</p>
</li>
</ol>
<h2 id="-">生产环境部署</h2>
<h3 id="-registry-">下载 Registry 源码并生成证书</h3>
<ol>
<li><p>下载 Registry <a href="https://github.com/docker/distribution/">docker/distribution</a> 源码：</p>
<pre><code class="lang-shell">mkdir docker &amp;&amp; cd docker &amp;&amp; git clone https://github.com/docker/distribution.git
</code></pre>
</li>
<li><p>进入 <code>distribution</code> 目录，并新建 <code>certs</code>子目录：</p>
<pre><code class="lang-shell">cd distribution &amp;&amp; mkdir certs
</code></pre>
</li>
<li><p>使用 SSL 生成自签名证书：</p>
<pre><code class="lang-shell">openssl req \
        -newkey rsa:2048 -nodes -keyout certs/domain.key \
        -x509 -days 365 -out certs/domain.crt
</code></pre>
</li>
<li><p>列出 <code>certs</code> 目录的内容：</p>
<pre><code class="lang-shell">ls certs
</code></pre>
</li>
</ol>
<h4 id="-registry-">构建并运行 Registry 镜像</h4>
<ol>
<li><p>构建：</p>
<pre><code class="lang-shell">docker build -t secure_registry
</code></pre>
</li>
<li><p>运行新镜像：</p>
<pre><code class="lang-shell">docker run -d -p 5000:5000 --restart=always --name registry \
  -v `pwd`/certs:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  secure_registry
</code></pre>
</li>
<li><p>使用 <code>curl</code> 验证 <code>https</code> 连接：</p>
<pre><code class="lang-shell">curl -v --insecure https://localhost:5000/v2/_catalog
</code></pre>
</li>
</ol>
<h2 id="-">参考</h2>
<ol>
<li><a href="https://docs.docker.com/registry/spec/api/#detail">Docker Registry HTTP API V2</a></li>
<li><a href="https://hub.docker.com/explore/">Docker Hub</a></li>
<li><a href="https://github.com/docker/distribution/blob/master/docs/insecure.md">Insecure Registry</a></li>
<li><a href="http://livedig.com/686#comment-352">部署 Docker Registry 服务</a></li>
<li><a href="http://unixman.blog.51cto.com/10163040/1707423">Docker Registry V2(distribution) &amp; Proxy(nginx) 的搭建经历</a></li>
<li><a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-14-04">How To Set Up a Private Docker Registry on Ubuntu 14.04</a></li>
</ol>

      </div>
      <div class="col-md-3" style="padding-top:20px;">
        <iframe src="http://githubbadge.appspot.com/tingge?a=0" style="border: 0;height: 142px;width: 200px;overflow: hidden;" frameBorder="0"></iframe>
      </div>
    </div>
  </div>
  <a id="html2canvas" title="截图下载-快照">&nbsp;</a>
  <script src="/lib/bootstrap/dist/js/bootstrap.min.js"></script>
  <script src="/js/article.js" charset="utf-8"></script>
  <!-- justice.js https://github.com/okor/justice  -->
  <script src="/lib/justice.min.js" charset="utf-8"></script>
  <!-- instantclick -->
  <script src="/lib/instantclick.js" charset="utf-8"></script>
  <script type="text/javascript" data-no-instant>
    Justice.init();
  </script>
</body>

</html>
